package cn.virens.mybatis;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import cn.virens.common.exception.APIException;
import cn.virens.mybatis.mapper.Mapper;
import cn.virens.mybatis.mapper.example.Example;
import cn.virens.mybatis.page.PageParamUser;
import cn.virens.mybatis.page.PageResult;
import cn.virens.mybatis.page.PageResultQuery;

/**
 * 通用service实现类
 * 
 * @author     virens
 * @param  <M> DO层接口类型
 * @param  <T> 实体类型
 */
public abstract class BaseReadServiceImpl<M extends Mapper<T>, T extends BaseModel> implements BaseReadService<T> {
	protected final Logger logger = LoggerFactory.getLogger(getClass());

	protected final Class<T> clazz;

	@Autowired
	protected M mBaseMapper;

	public BaseReadServiceImpl(Class<T> clazz) {
		this.clazz = clazz;
	}

	@Override
	@Transactional(readOnly = true)
	public List<? extends T> selectAll(Map<String, Object> param) {
		return mBaseMapper.selectByExample(Example.newInstance());
	}

	@Override
	@Transactional(readOnly = true)
	public T selectOne(Serializable id) throws APIException {
		return mBaseMapper.selectByPrimaryKey(id).orElse(null);
	}

	@Override
	@Transactional(readOnly = true)
	public PageResult<?> selectPage(PageParamUser pageParam) {
		return PageResultQuery.selectPage(pageParam, (w) -> doPageQuery(w));
	}

	/**
	 * 查询一条记录
	 * 
	 * @param  example 查询条件
	 * @return         记录
	 */
	protected T selectOne(Example example) throws APIException {
		return mBaseMapper.selectOneByExample(example);
	}

	/**
	 * 默认查询全部，如需使用分页，并且有条件查询，复写该方法
	 * 
	 * @param  param 查询参数
	 * @return       记录列表
	 */
	protected List<?> doPageQuery(PageResultQuery query) {
		return selectAll(query.params());
	}
}
